package com.ben.restjpademo.service;


import com.ben.restjpademo.dao.CrawlerJobRepository;
import com.ben.restjpademo.dao.CrawlerRepository;
import com.ben.restjpademo.dao.ScheduleRepository;
import com.ben.restjpademo.domain.Crawler;

import com.ben.restjpademo.domain.CrawlerJob;
import com.ben.restjpademo.domain.Schedule;
import net.sf.json.JSONObject;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.regex.*;
import org.springframework.web.client.RestTemplate;
import net.sf.json.JSONArray;

@Controller
@RequestMapping("api")
public class CrawlerController {

    String patternPercent = "\\d+\\.\\d+(?=%)";
    String patternTotal = "(?<=Totaly : )\\d+";
    String patternAccurent = "(?<=got )\\d+";
    @Resource
    CrawlerRepository crawlerRepository;

    @Resource
    CrawlerJobRepository crawlerJobRepository;

    @Resource
    ScheduleRepository scheduleRepository;

    RestTemplate restTemplate = new RestTemplate();
    String spiderUrl = "http://localhost:6800/listspiders.json?project=vul";
    String jobUrl = "http://localhost:6800/listjobs.json?project=vul";
    String createCrawlerUrl = "http://localhost:6800/schedule.json";
    String cancelCrawlerUrl = "http://localhost:6800/cancel.json";

    @ResponseBody
    @RequestMapping(value = "crawlers", method = RequestMethod.GET)
    public List<Crawler> findCrawlers() {

        JSONObject spiderJson = restTemplate.getForEntity(spiderUrl, JSONObject.class).getBody();

        String spiderStatus = spiderJson.get("status").toString();


        if (spiderStatus.equals("ok")){
            JSONArray spiders=spiderJson.getJSONArray("spiders");
            if(spiders.isEmpty()!=true) {


                for (int i = 0; i < spiders.size(); i++) {
                    if(crawlerRepository.findBySpiderName(spiders.get(i).toString()) !=null){
                        continue;
                    }
                    Crawler crawler = new Crawler();
                    crawler.setSpiderName(spiders.get(i).toString());
                    crawlerRepository.save(crawler);
                }
            }
        }

        List<Crawler> crawlers = crawlerRepository.findAll();
        return crawlers;
    }


    @ResponseBody
    @RequestMapping(value = "jobs", method = RequestMethod.GET)
    public List<CrawlerJob> findJobs() {

        List<CrawlerJob> jobs = crawlerJobRepository.findAll();
        return jobs;
    }

    @ResponseBody
    @RequestMapping(value = "jobs/{id}", method = RequestMethod.GET)
    public CrawlerJob findJobById(@PathVariable("id") String id) {

        CrawlerJob job = crawlerJobRepository.findByJobId(id);
        return job;
    }

    @ResponseBody
    @RequestMapping(value={"crawlers/create"}, method=RequestMethod.POST)
    /**/
    public String createCrawlerJob(@RequestBody String spiderName) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);

        MultiValueMap<String, Object> data =
                new LinkedMultiValueMap<String, Object>();

        data.add("project", "vul");
        data.add("spider", spiderName.replaceAll("\"", ""));

        HttpEntity<MultiValueMap<String, Object>> createJob =
                new HttpEntity<MultiValueMap<String, Object>>(data, headers);

        JSONObject json = restTemplate.postForEntity(createCrawlerUrl, createJob, JSONObject.class).getBody();

        String jobId = json.get("jobid").toString();


//        try {
//            Thread.sleep(2000);                 //1000 毫秒，也就是1秒.
//        } catch(InterruptedException ex) {
//            Thread.currentThread().interrupt();
//        }
        JSONObject runingJob = new JSONObject();
        Boolean breakFlag = Boolean.FALSE;
        for(;;){
            JSONObject jobJson = restTemplate.getForEntity(jobUrl, JSONObject.class).getBody();
            JSONArray runingJobs = jobJson.getJSONArray("running");
            if(runingJobs.isEmpty()!=true){
                for (int i = 0; i < runingJobs.size(); i++) {
                    JSONObject runingJobTemp = (JSONObject) runingJobs.get(i);

                    if (runingJobTemp.get("id").toString().equals(jobId)) {
                        runingJob = runingJobTemp;
                        breakFlag = Boolean.TRUE;
                        break;
                    }
                }

            }
            if(breakFlag == Boolean.TRUE){
                break;
            }
            try {
                Thread.sleep(500);                 //1000 毫秒，也就是1秒.
            }
            catch(InterruptedException ex) {
                Thread.currentThread().interrupt();
            }
        }


        CrawlerJob crawlerjob =new CrawlerJob();
        crawlerjob.setStatus("running");
        crawlerjob.setSpiderName(runingJob.get("spider").toString());
        crawlerjob.setStartTime(runingJob.get("start_time").toString());
        crawlerjob.setJobId(jobId);
        crawlerJobRepository.save(crawlerjob);



        return jobId;
    }

    @ResponseBody
    @RequestMapping(value={"crawlers/cancel"}, method=RequestMethod.POST)
    public String cancelCrawlerJob(@RequestBody String jobId) {
        jobId = jobId.replaceAll("\"","");
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);

        MultiValueMap<String, Object> data =
                new LinkedMultiValueMap<String, Object>();

        data.add("project","vul");
        data.add("job",jobId);

        HttpEntity<MultiValueMap<String, Object>> cancelJob =
                new HttpEntity<MultiValueMap<String, Object>>(data, headers);

        JSONObject json = restTemplate.postForEntity(cancelCrawlerUrl, cancelJob, JSONObject.class).getBody();

//        try {
//            Thread.sleep(2000);                 //1000 毫秒，也就是1秒.
//        } catch(InterruptedException ex) {
//            Thread.currentThread().interrupt();
//        }
        JSONObject finishedJob = new JSONObject();
        Boolean breakFlag = Boolean.FALSE;
        for(;;){
            JSONObject jobJson = restTemplate.getForEntity(jobUrl, JSONObject.class).getBody();
            JSONArray finishedJobs = jobJson.getJSONArray("finished");
            if(finishedJobs.isEmpty()!=true){
                for (int i = 0; i < finishedJobs.size(); i++) {
                    JSONObject finishedJobTemp = (JSONObject) finishedJobs.get(i);

                    if (finishedJobTemp.get("id").toString().equals(jobId)) {
                        finishedJob = finishedJobTemp;
                        breakFlag = Boolean.TRUE;
                        break;
                    }
                }

            }
            if(breakFlag == Boolean.TRUE){
                break;
            }
            try {
                Thread.sleep(500);                 //1000 毫秒，也就是1秒.
            }
            catch(InterruptedException ex) {
                Thread.currentThread().interrupt();
            }
        }



        //cd.out.println(finishedJob.toString());



        CrawlerJob crawlerjob = crawlerJobRepository.findByJobId(jobId);

        crawlerjob.setStatus("finished");
        crawlerjob.setEndTime(finishedJob.get("end_time").toString());
        crawlerJobRepository.save(crawlerjob);

     //   System.out.println("停止的job：" + json.toString());

        return jobId;

    }


    @ResponseBody
    @RequestMapping(value={"/jobs/delete/{id}"}, method=RequestMethod.DELETE)
    /**/
    public CrawlerJob deleteJob(@PathVariable("id") String id) {
        //System.out.println("aaaaaaaaaaaaa:"+id);
        CrawlerJob crawlerjob = crawlerJobRepository.findByJobId(id);
     //   System.out.println("删除的job："+crawlerjob.getJobId());

        crawlerJobRepository.delete(crawlerjob);
        return crawlerjob;

    }

    @ResponseBody
    @RequestMapping(value = "jobs/totals/{spider}/{id}", method = RequestMethod.GET)
    public String findTotal(@PathVariable("id") String id,@PathVariable("spider") String spider) {
        String url = "http://localhost:6800/logs/vul/"+spider+"/"+id+".log";
        //System.out.println(url);

        String text = restTemplate.getForEntity(url,String.class).getBody();
        String num = "0";
        Pattern total = Pattern.compile(patternTotal);
        Matcher m = total.matcher(text);

        while(m.find()){
            num = m.group();
        }
        CrawlerJob job = crawlerJobRepository.findByJobId(id);
        job.setTotal(num);
        crawlerJobRepository.save(job);
        //System.out.println(num);
        return num;
    }

    @ResponseBody
    @RequestMapping(value = "jobs/percent/{spider}/{id}", method = RequestMethod.GET)
    public String findPercent(@PathVariable("id") String id,@PathVariable("spider") String spider) {
        String url = "http://localhost:6800/logs/vul/"+spider+'/'+id+".log";
        //System.out.println(url);
        String text = restTemplate.getForEntity(url,String.class).getBody();
        String percent = "0";
        Pattern total = Pattern.compile(patternPercent);
        Matcher m = total.matcher(text);
        while(m.find()){
            percent= m.group();
        }
        CrawlerJob job = crawlerJobRepository.findByJobId(id);
        job.setCurrent(percent);
        crawlerJobRepository.save(job);
        //System.out.println(percent);
        return percent;
    }

}
